package com.atguigu.juc.locks;

import org.junit.jupiter.api.Test;

/**
 * @author yanglin
 * @create 2024-01-07 16:01 星期日
 * description:
 */
public class LockSyncDemo {

    /**
     * 面试题：为什么任何一个对象都可以成为一个锁？
     *      因为每一个对象，天生都带有一个对象监视器，每一个被锁住的对象都会和Monitor关联起来
     *  管程：（Monitors，也称监视器）是一种程序结构，结构内的多个子程序（对象或模块）形成的多个工作线程互斥访问共享资源
     */


    Object object = new Object();

    /**
     * synchronized同步代码块实现原理：
     *  通过 javap -c .\LockSyncDemo.class 反编译命令，可看出：是通过monitorenter和monitorexit指令实现的
     *      一般情况下：一个monitorenter 对应两个 monitorexit
     */
    public void m1(){
        synchronized (object){
            System.out.println("hello synchronized code block");
        }
        
    }

    /**
     * synchronized普通同步方法：
     *  通过 javap -v .\LockSyncDemo.class（相比于javap -v 输出的反编译信息更加详细）反编译
     *      调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置
     *          如果设置了，执行线程将会先持有monitor锁，然后在执行方法，
     *          最后在方法执行完成（无论时正常还是异常）时释放
     */
    public synchronized void m2(){
        System.out.println("hello synchronized code block 2");
    }


    /**
     * 静态同步代码块：
     *  通过 javap -v 的反编译命令可以得出：
     *       ACC_STATIC, ACC_SYNCHRONIZED 访问标志来区分该方法是否是静态同步方法
     */
    public static synchronized void m3(){
        System.out.println("hello synchronized code block 3");
    }
    
    @Test
    public void testLockSync(){ 
        
    }
    
}
